package com.duoduo.mall.service.impl;

import com.duoduo.mall.dto.LoginDTO;
import com.duoduo.mall.dto.PasswordUpdateDTO;
import com.duoduo.mall.dto.RegisterDTO;
import com.duoduo.mall.dto.UserUpdateDTO;
import org.apache.tomcat.jni.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.duoduo.mall.utils.PageUtils;
import com.duoduo.mall.utils.Query;

import com.duoduo.mall.dao.UserDao;
import com.duoduo.mall.entity.UserEntity;
import com.duoduo.mall.service.UserService;
import com.duoduo.mall.vo.LoginVO;
import com.duoduo.mall.vo.UserVO;
import com.duoduo.mall.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.beans.BeanUtils;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

@Service("userService")
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Autowired
    private HttpServletRequest request;

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public void register(RegisterDTO registerDTO) {
        // 1. 检查用户名是否已存在
        UserEntity existUser = this.baseMapper.selectOne(
                new QueryWrapper<UserEntity>().eq("username", registerDTO.getUsername()));
        if (existUser != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 2. 创建新用户
        UserEntity user = new UserEntity();
        user.setUsername(registerDTO.getUsername());
        // 使用BCrypt加盐
        // 直接加密密码，盐值会自动包含在加密结果中
        BeanUtils.copyProperties(registerDTO, user);
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
        user.setType(1); // 默认普通用户
        // user.setStatus(1); // 默认正常状态---数据库已设置默认为1：正常
        this.save(user);
    }

    @Override
    public LoginVO login(LoginDTO loginDTO) {
        // 1. 查询用户
        UserEntity user = this.baseMapper.selectOne(
                new QueryWrapper<UserEntity>()
                        .eq("username", loginDTO.getUsername()));

        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 2. 校验密码
        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        if (user.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }

        // 3. 生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("username", user.getUsername());
        String token = JwtUtils.generateJwt(claims);

        // 4. 构建返回数据
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(token);
        loginVO.setUserInfo(convertToUserVO(user));

        return loginVO;
    }

    // 获取当前登录用户
    private UserEntity getCurrentUser() {
        Claims claims = JwtUtils.parseJWT(request.getHeader("token"));
        Long userId = claims.get("userId", Long.class);
        UserEntity currentUser = getById(userId);
        if (currentUser == null) {
            throw new RuntimeException("用户不存在");
        }
        return currentUser;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        // 1. 验证当前用户是否是管理员
        UserEntity currentUser = this.getCurrentUser();
        if (currentUser.getType() != 3) { // 3-管理员
            throw new RuntimeException("无权限访问");
        }

        // 2. 构建查询条件
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<UserEntity>()
                // 只查询普通用户和VIP用户(type=1或2)
                .in("type", Arrays.asList(1, 2));

        // 4. 先查询总记录数
        long total = this.count(queryWrapper);

        // 5. 再查询分页数据
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                queryWrapper);

        page.setTotal(total);
        return new PageUtils(page);
    }

    @Override
    public UserVO getUserInfoById(Long id) {
        // 1. 获取当前登录用户
        UserEntity currentUser = this.getCurrentUser();

        // 2. 验证当前用户是否是管理员
        if (currentUser.getType() != 3) { // 假设3是管理员类型
            throw new RuntimeException("无权限访问");
        }

        // 3. 获取目标用户信息
        UserEntity targetUser = this.getById(id);
        if (targetUser == null) {
            throw new RuntimeException("查询的用户不存在");
        }

        // 4. 验证目标用户是否为普通用户或商家
        if (targetUser.getType() != 1 || targetUser.getType() != 2) { // 查询的是普通用户的id和商家的id
            throw new RuntimeException("只能查看普通用户信息");
        }

        // 5. 转换为VO并返回
        return convertToUserVO(targetUser);
    }

    // 查看当前用户信息
    @Override
    public UserVO getCurrentUserInfo() {
        // 1. 获取当前登录用户
        UserEntity currentUser = this.getCurrentUser();
        UserEntity user = this.getById(currentUser.getId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        return convertToUserVO(user);
    }

    // 更新当前用户信息
    @Override
    public void updateCurrentUserInfo(UserUpdateDTO userUpdateDTO) {
        UserEntity currentUser = this.getCurrentUser();
        Long userId = currentUser.getId();
        UserEntity user = this.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        UserEntity updateUser = new UserEntity();
        updateUser.setId(userId);
        BeanUtils.copyProperties(userUpdateDTO, updateUser);
        this.updateById(updateUser);
    }

    @Override
    public void updatePassword(PasswordUpdateDTO passwordUpdateDTO) {
        UserEntity currentUser = this.getCurrentUser();

        // 验证原密码
        if (!passwordEncoder.matches(passwordUpdateDTO.getOldPassword(), currentUser.getPassword())) {
            throw new RuntimeException("原密码错误");
        }

        // 验证新密码不能与原密码相同
        if (passwordEncoder.matches(passwordUpdateDTO.getNewPassword(), currentUser.getPassword())) {
            throw new RuntimeException("新密码不能与原密码相同");
        }

        // 更新密码
        UserEntity updateUser = new UserEntity();
        updateUser.setId(currentUser.getId());
        updateUser.setPassword(passwordEncoder.encode(passwordUpdateDTO.getNewPassword()));
        this.updateById(updateUser);
    }

    @Override
    public void deleteUsersByIds(List<Long> ids) {
        // 1. 验证当前用户是否是管理员
        UserEntity currentUser = this.getCurrentUser();
        if (currentUser.getType() != 3) {
            throw new RuntimeException("无权限访问");
        }

        // 2. 查询要删除的用户列表
        List<UserEntity> userList = this.listByIds(ids);

        // 3. 验证用户列表
        for (UserEntity user : userList) {
            // 验证是否为普通用户或VIP用户
            if (user.getType() == 3) {
                throw new RuntimeException("不能删除管理员账号");
            }
        }

        // 4. 执行批量删除
        this.removeByIds(ids);
    }

    /**
     * 将实体转换为VO
     */
    private UserVO convertToUserVO(UserEntity user) {
        if (user == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

}